﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ERPStore.Extensions;

using CloudSoft.Extensions;

namespace ERPStore.Cart.Repositories
{
	public static class ModelConverter
	{
		public static ERPStore.Models.CartItem ToCartItemModel(this Datas.CartItem itemData, ERPStore.Models.Product product)
		{
			if (product == null
				|| itemData == null)
			{
				return null;
			}
			var cartItem = new ERPStore.Models.CartItem();
			cartItem.Id = itemData.Id;
			cartItem.Packaging = product.Packaging.Value;
			cartItem.Product = product;
			cartItem.Quantity = itemData.Quantity;
			cartItem.RecyclePrice = product.RecyclePrice;
			cartItem.SalePrice = new ERPStore.Models.Price(itemData.SalePrice / 1000000.0, product.DefaultTaxRate);
			cartItem.SaleUnitValue = product.SaleUnitValue;
			cartItem.AllowPartialDelivery = itemData.AllowPartialDelivery;
			cartItem.CreationDate = itemData.CreationDate;
			cartItem.LastUpdate = itemData.LastUpdate;
			cartItem.Discount = itemData.Discount / 10000.0;

			if (itemData.ShippingTypeId == (int)Models.ShippingType.WhenAvailable)
			{
				cartItem.ShippingType = ERPStore.Models.ShippingType.WhenAvailable;
			}
			else if (itemData.ShippingTypeId == (int)Models.ShippingType.FixedDelay)
			{
				cartItem.ShippingType = ERPStore.Models.ShippingType.FixedDelay;
			}
			else if (itemData.ShippingTypeId == (int)Models.ShippingType.Deadline)
			{
				cartItem.ShippingType = ERPStore.Models.ShippingType.Deadline;
			}

			cartItem.IsLocked = itemData.IsLocked;
			cartItem.CatalogPrice = product.SalePrice;
			cartItem.AddFrom = itemData.AddFrom;
			cartItem.OfferName = itemData.OfferName;
			cartItem.InventoryTimeStateId = itemData.InventoryTimeStateId;

			return cartItem;
		}

		public static ERPStore.Models.OrderCart ToOrderCartModel(this Datas.Cart cartData)
		{
			if (cartData == null)
			{
				return null;
			}

			var addressService = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Services.IAddressService>();
			var accountService = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Services.IAccountService>();

			var cart = new ERPStore.Models.OrderCart();
			cart.Id = cartData.Id;
			cart.AllowPartialDelivery = cartData.AllowPartialDelivery;
			cart.Code = cartData.Code;
			cart.CreationDate = cartData.CreationDate;
			cart.CustomerDocumentReference = cartData.CustomerDocumentReference;
			cart.CustomerId = cartData.CustomerPersonId;
			cart.Message = cartData.Message;
			cart.VisitorId = cartData.VisitorId;
			cart.AcceptCondition = cartData.AcceptTermsAndConditions;
			cart.IsActive = cartData.CartStateId == (int)ERPStore.Models.CartState.CurrentOrder;
			cart.LastPage = cartData.LastPage;
			cart.FromEntityId = cartData.FromEntityId;
			cart.FromMetaEntityId = cartData.FromMetaEntityId;
			cart.LeadSourceName = cartData.LeadSourceName;
			cart.LeadSourceId = cartData.LeadSourceId;
			cart.ConversionDate = cartData.ConversionDate;
			cart.ConvertedEntityId = cartData.ConvertedEntityId;
			cart.ShippingFeeLocked = cartData.ShippingFeeLocked;
			cart.MessageForConveyor = cartData.MessageForConveyor;

			if (cartData.DeliveryAddressId.GetValueOrDefault(0) != 0)
			{
				cart.DeliveryAddress = addressService.GetAddressById(cartData.DeliveryAddressId.Value);
			}

			if (cartData.CustomerPersonId.HasValue)
			{
				var user = accountService.GetUserById(cartData.CustomerPersonId.Value);

				if (user != null)
				{
					cart.BillingAddress = user.DefaultAddress;

					if (cart.DeliveryAddress == null 
						&& cartData.DeliveryAddressId.HasValue
						&& cartData.DeliveryAddressId.Value != 0)
					{
						var deliveryAddress = user.DeliveryAddressList.SingleOrDefault(i => i.Id == cartData.DeliveryAddressId.Value);
						if (deliveryAddress != null)
						{
							cart.DeliveryAddress = deliveryAddress;
						}
						else
						{
							cart.DeliveryAddress = addressService.GetAddressById(cartData.DeliveryAddressId.Value);
						}
					}
				}
			}

			cart.IsPresent = cartData.IsPresent;
			if (!cartData.PaymentModeName.IsNullOrTrimmedEmpty())
			{
				cart.PaymentModeName = cartData.PaymentModeName;
			}
			cart.ShippingFee = new ERPStore.Models.Fee();
			cart.ShippingFee.Amount = cartData.ShippingFeeAmount.GetValueOrDefault(0) / 1000000m;
			cart.ShippingFee.TaxRate = cartData.ShippingFeeTaxRate.GetValueOrDefault(0) / 10000d;
			if (cartData.ConveyorId.HasValue)
			{
				cart.Conveyor = accountService.GetConveyorById(cartData.ConveyorId.Value);
				if (cart.Conveyor == null)
				{
					cart.Conveyor = accountService.GetConveyorList().First();
				}
			}
			if (cartData.CartStateId != 0)
			{
				cart.State =  (ERPStore.Models.CartState) Enum.Parse(typeof(ERPStore.Models.CartState), cartData.CartStateId.ToString());
			}

			var catalogService = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Services.ICatalogService>();
			var productIdList = cartData.Items.Select(i => i.ProductId);
			var productList = catalogService.GetProductListByIdList(productIdList, false);
			foreach (var cartItemData in cartData.Items)
			{
				if (cartItemData.IsArchived)
				{
					continue;
				}
				var product = productList.FirstOrDefault(i => i.Id == cartItemData.ProductId);
				var cartItem = cartItemData.ToCartItemModel(product);
				if (cartItem != null)
				{
					cart.Items.Add(cartItem);
				}
			}

			var incentiveService = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Services.IIncentiveService>();
			incentiveService.LoadCouponList(cart);

			return cart;
		}

		internal static Datas.Cart ToCartData(this ERPStore.Models.OrderCart model)
		{
			var cartData = new Datas.Cart();
			cartData.Id = model.Id;
			cartData.Code = model.Code;
			cartData.CreationDate = DateTime.Now;
			cartData.CartStateId = (int)ERPStore.Models.CartState.CurrentOrder;

			cartData.CustomerDocumentReference = model.CustomerDocumentReference;
			cartData.CustomerPersonId = model.CustomerId;
			cartData.LastUpdate = DateTime.Now;
			cartData.Message = model.Message;
			cartData.VisitorId = model.VisitorId;
			cartData.LastPage = model.LastPage;
			cartData.LeadSourceName = model.LeadSourceName;
			cartData.LeadSourceId = model.LeadSourceId;

			if (model.DeliveryAddress != null)
			{
				cartData.DeliveryAddressId = model.DeliveryAddress.Id;
			}
			cartData.IsPresent = model.IsPresent;
			cartData.PaymentModeName = model.PaymentModeName;
			cartData.ShippingFeeAmount = Convert.ToInt64(model.ShippingFee.Amount * 1000000);
			cartData.ShippingFeeTaxRate = Convert.ToInt32(model.ShippingFee.TaxRate * 10000);
			cartData.AllowPartialDelivery = model.AllowPartialDelivery;
			cartData.FromEntityId = model.FromEntityId;
			cartData.FromMetaEntityId = model.FromMetaEntityId;
			cartData.ShippingFeeLocked = model.ShippingFeeLocked;
			if (model.Conveyor != null)
			{
				cartData.ConveyorId = model.Conveyor.Id;
			}
			cartData.AcceptTermsAndConditions = model.AcceptCondition;
			cartData.MessageForConveyor = model.MessageForConveyor;

			if (model.ConvertedEntityId.HasValue)
			{
				cartData.ConvertedEntityId = model.ConvertedEntityId.Value;
				cartData.ConversionDate = DateTime.Now;
				cartData.CartStateId = (int)ERPStore.Models.CartState.ConvertedToOrder;
			}
			else
			{
				cartData.ConvertedEntityId = model.ConvertedEntityId;
				cartData.ConversionDate = model.ConversionDate;
			}

			cartData.Items = new List<Datas.CartItem>();
			foreach (var cartItemModel in model.Items)
			{
				cartData.Items.Add(cartItemModel.ToCartItemData(cartData));
			}

			return cartData;
		}

		internal static Datas.CartItem ToCartItemData(this ERPStore.Models.CartItem cartItem, Datas.Cart cartData)
		{
			var cartItemData = new Datas.CartItem();
			cartItemData.CartId = cartData.Id;
			cartItemData.ProductId = cartItem.Product.Id;
			cartItemData.CreationDate = cartItem.CreationDate;
			cartItemData.LastUpdate = cartItem.LastUpdate;
			cartItemData.Quantity = cartItem.Quantity;
			cartItemData.SalePrice = Convert.ToInt64(cartItem.SalePrice.Value * 1000000);
			cartItemData.Discount = Convert.ToInt32(cartItem.Discount * 10000);

			switch (cartItem.ShippingType)
			{
				case ERPStore.Models.ShippingType.WhenAvailable:
					cartItemData.ShippingTypeId = (int)Models.ShippingType.WhenAvailable;
					break;
				case ERPStore.Models.ShippingType.FixedDelay:
					cartItemData.ShippingTypeId = (int)Models.ShippingType.FixedDelay;
					break;
				case ERPStore.Models.ShippingType.Deadline:
					cartItemData.ShippingTypeId = (int)Models.ShippingType.Deadline;
					break;
				default:
					break;
			}

			cartItemData.AllowPartialDelivery = cartItem.AllowPartialDelivery;
			cartItemData.AddFrom = cartItem.AddFrom;
			cartItemData.OfferName = cartItem.OfferName;
			cartItemData.InventoryTimeStateId = cartItem.InventoryTimeStateId;

			return cartItemData;
		}

	}
}
